package su2010.puz.main;

import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;

import com.pearsoneduc.ip.op.HistogramException;

import su2010.puz.CloseButton;
import su2010.puz.Extractor;
import su2010.puz.FeatureVector;
import su2010.puz.ImageHelper;
import su2010.puz.classifiers.Classification;
import su2010.puz.extractors.DifferencePixelExtractor;
import su2010.puz.extractors.HistogramExtractor;
import su2010.puz.extractors.HistogramMaxima;
import su2010.puz.extractors.HistogramPeakExtractor;
import su2010.puz.extractors.PixelIntervalExtractor;
import su2010.puz.extractors.RatioExtractor;
import su2010.puz.extractors.SymmetryExtractor;
import su2010.puz.impl.BoxBlurFilter;
import su2010.puz.impl.CannyEdgeFilter;
import su2010.puz.impl.Histogram;
import su2010.puz.impl.SharpenFilter;
import su2010.puz.impl.SmartBlurFilter;
import su2010.puz.impl.SymmetrifyFilter;
import su2010.puz.util.ColorConvert;
import su2010.puz.util.ImageCls;
import su2010.puz.util.SetCreator;
import weka.classifiers.Classifier;
import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.functions.SMO;

public class Starter {
	
	static Classification klas = null;
	
	public static void main(String[] args) throws IOException, HistogramException {
		
		//fixExtensions("images2");
		
//		loadFromFile(new NaiveBayes(),"pu02.arff", 80);
	
		long start = System.currentTimeMillis();
		createNew(new SMO(), "images2", 90, 90, "BrunoDB_ALL2.arff");
		klas.train();
		klas.test();
		long time = System.currentTimeMillis() - start;
		System.out.println("Time elapsed: "+time/1000f+"s ("+time/60000+"min)");//*/
		/*
		new CloseButton();
		
		//ImageHelper.showImage(image.getImage(), "Slika");
		ImageCls image = ImageHelper.readImage("images/i_realism.jpg");
		ImageHelper.showImage(image.getImage(), "Slika");
		ImageHelper.showImage(new SymmetrifyFilter(true).apply(image.getImage()), "Slika");
		ImageHelper.showImage(new SymmetrifyFilter(false).apply(image.getImage()), "Slika");
				
		PixelIntervalExtractor pie = new PixelIntervalExtractor();
		pie.setColorMode(ImageHelper.LUMINANCE);
		pie.setInterval(0, 64);
		pie.setFilter(new SymmetrifyFilter(true));
		pie.setImage(image);
		
		FloatArrayPrinter(pie.extract(), "PIE 1..255");
		pie.setInterval(64, 255 );
		pie.setImage(image);
		FloatArrayPrinter(pie.extract(), "PIE 64..255");
		pie.setInterval(0, 64 );
		pie.setImage(image);
		FloatArrayPrinter(pie.extract(), "PIE 0..64");
		
		
		/*
		SymmetryExtractor se = new SymmetryExtractor();
		se.setDivision(5);
		ImageCls image = ImageHelper.readImage("images/redsquare.jpg");
		se.setImage(image);
		FloatArrayPrinter(se.extract(), "symp");
		
		image = ImageHelper.readImage("images/kubizam.jpg");
		se.setImage(image);
		FloatArrayPrinter(se.extract(), "symk");
		
		image = ImageHelper.readImage("images/fauvism.jpg");
		se.setImage(image);
		FloatArrayPrinter(se.extract(), "symf");
		//--------------------
		se.setFilters(new BoxBlurFilter(5,5,3));
		image = ImageHelper.readImage("images/pointilism.jpg");
		se.setImage(image);
		FloatArrayPrinter(se.extract(), "symp");
		
		image = ImageHelper.readImage("images/kubizam.jpg");
		se.setImage(image);
		FloatArrayPrinter(se.extract(), "symk");
		
		image = ImageHelper.readImage("images/fauvism.jpg");
		se.setImage(image);
		FloatArrayPrinter(se.extract(), "symf");*/
		
	}
	
	/**
	 * Loading classification from arff file
	 * @param classifier instance of wanted classifier
	 * @param loadPath path to data
	 * @param percentage percentage of used data for training
	 */
	public static void loadFromFile(Classifier classifier, String loadPath, int percentage){
		klas = new Classification(classifier, loadPath, 80);
	}
	
	/**
	 * Creating new data from images
	 * @param classifier instance of wanted classifier
	 * @param database path to image database
	 * @param percentage percentage of used images for training
	 * @param savePath path to arff for saving (can be null if saving is not wanted)
	 * @throws IOException
	 */
	public static void createNew(Classifier classifier, String database,int percentage, int imgPerClas, String savePath) throws IOException{
		List<Extractor> extractors = new ArrayList<Extractor>();
		
		/*
		 * Stavljene su sve značajke tako da mogu za dokumentaciju 
		 * istinito napisati što je najkorisnije.
		 *
		 *
		 * -------------------------------------------------------------------------------
		 *
		 *
		 * HISTOGRAM EXTRACTORS:
		 * RGBHSLV
		 */
		HistogramExtractor hisExtractor;
		
		hisExtractor = new HistogramExtractor();
		hisExtractor.setColorMode(ImageHelper.RED);
		extractors.add(hisExtractor);
		
		hisExtractor = new HistogramExtractor();
		hisExtractor.setColorMode(ImageHelper.GREEN);
		extractors.add(hisExtractor);
		
		hisExtractor = new HistogramExtractor();
		hisExtractor.setColorMode(ImageHelper.BLUE);
		extractors.add(hisExtractor);
		
		hisExtractor = new HistogramExtractor();
		hisExtractor.setColorMode(ImageHelper.HUE);
		extractors.add(hisExtractor);

		hisExtractor = new HistogramExtractor();
		hisExtractor.setColorMode(ImageHelper.SATURATION);
		extractors.add(hisExtractor);
		
		hisExtractor = new HistogramExtractor();
		hisExtractor.setColorMode(ImageHelper.LUMINANCE);
		extractors.add(hisExtractor);
		
		hisExtractor = new HistogramExtractor();
		hisExtractor.setColorMode(ImageHelper.VALUE);
		extractors.add(hisExtractor);
		
		/*
		 * HISTOGRAM MAXIMA
		 * HSLV
		 */		
		HistogramMaxima histogramMaxima = new HistogramMaxima();
		histogramMaxima.setColor_mode(ImageHelper.HUE);
		extractors.add(histogramMaxima);
		
		histogramMaxima = new HistogramMaxima();
		histogramMaxima.setColor_mode(ImageHelper.SATURATION);
		extractors.add(histogramMaxima);
		
		histogramMaxima = new HistogramMaxima();
		histogramMaxima.setColor_mode(ImageHelper.LUMINANCE);
		extractors.add(histogramMaxima);
		
		histogramMaxima = new HistogramMaxima();
		histogramMaxima.setColor_mode(ImageHelper.VALUE);
		extractors.add(histogramMaxima);
		
		/*
		 * HISTOGRAM PEAK
		 * HSLV
		 */
		HistogramPeakExtractor histogramPeakExtractor = new HistogramPeakExtractor();
		histogramPeakExtractor.setColorMode(ImageHelper.HUE);
		extractors.add(histogramPeakExtractor);
		
		histogramPeakExtractor = new HistogramPeakExtractor();
		histogramPeakExtractor.setColorMode(ImageHelper.SATURATION);
		extractors.add(histogramPeakExtractor);
		
		histogramPeakExtractor = new HistogramPeakExtractor();
		histogramPeakExtractor.setColorMode(ImageHelper.LUMINANCE);
		extractors.add(histogramPeakExtractor);
		
		histogramPeakExtractor = new HistogramPeakExtractor();
		histogramPeakExtractor.setColorMode(ImageHelper.VALUE);
		extractors.add(histogramPeakExtractor);
		
		/*
		 * DARK PIXEL RATIO
		 */		
		PixelIntervalExtractor darkPixelRatio = new PixelIntervalExtractor("Dark Pixel ratio");
		darkPixelRatio.setColorMode(ImageHelper.LUMINANCE);
		darkPixelRatio.setInterval(0, 63);
		extractors.add(darkPixelRatio);
		
		/*
		 * CANNY EDGE RATIOS
		 * no filter
		 * box blur
		 * smart blur
		 * sharpen sharpen
		 */
		PixelIntervalExtractor cannyEdgesRatio = new PixelIntervalExtractor("Canny Edges ratio");
		cannyEdgesRatio.setColorMode(ImageHelper.LUMINANCE);
		cannyEdgesRatio.setFilter(new SharpenFilter(), new CannyEdgeFilter());
		cannyEdgesRatio.setInterval(1, 255);
		extractors.add(cannyEdgesRatio);
		
		cannyEdgesRatio = new PixelIntervalExtractor("BoxBlur Canny Edges ratio");
		cannyEdgesRatio.setColorMode(ImageHelper.LUMINANCE);
		cannyEdgesRatio.setFilter(new BoxBlurFilter(), new CannyEdgeFilter());
		cannyEdgesRatio.setInterval(1, 255);
		extractors.add(cannyEdgesRatio);
		
		cannyEdgesRatio = new PixelIntervalExtractor("SmartBlur Canny Edges ratio");
		cannyEdgesRatio.setColorMode(ImageHelper.LUMINANCE);
		cannyEdgesRatio.setFilter(new SmartBlurFilter(), new CannyEdgeFilter());
		cannyEdgesRatio.setInterval(1, 255);
		extractors.add(cannyEdgesRatio);
		
		cannyEdgesRatio = new PixelIntervalExtractor("Sharpen Canny Edges ratio");
		cannyEdgesRatio.setColorMode(ImageHelper.LUMINANCE);
		cannyEdgesRatio.setFilter(new SharpenFilter(), new SharpenFilter(), new CannyEdgeFilter());
		cannyEdgesRatio.setInterval(1, 255);
		extractors.add(cannyEdgesRatio);
		
		
		/*
		 * ORIGINAL - SMART/BOX
		 */		
		DifferencePixelExtractor differencePixelExtractor = new DifferencePixelExtractor("Original - SmartBlur");
		differencePixelExtractor.setFirstFilters();
		differencePixelExtractor.setSecondFilters(new SmartBlurFilter());
		extractors.add(differencePixelExtractor);
		
		differencePixelExtractor = new DifferencePixelExtractor("Original - BoxBlur");
		differencePixelExtractor.setFirstFilters();
		differencePixelExtractor.setSecondFilters(new BoxBlurFilter());
		extractors.add(differencePixelExtractor);
		
		/*
		 * SYMMERTY - VERTICAL/HORISONTAL 
		 */
		PixelIntervalExtractor symmetryDarkInterval = new PixelIntervalExtractor("Symmetry-v darkness");
		symmetryDarkInterval.setColorMode(ImageHelper.LUMINANCE);
		symmetryDarkInterval.setInterval(0, 64);
		symmetryDarkInterval.setFilter(new SymmetrifyFilter(true));		
		extractors.add(symmetryDarkInterval);
		
		symmetryDarkInterval = new PixelIntervalExtractor("Symmetry-h darkness");
		symmetryDarkInterval.setColorMode(ImageHelper.LUMINANCE);
		symmetryDarkInterval.setInterval(0, 64);
		symmetryDarkInterval.setFilter(new SymmetrifyFilter(false));
		extractors.add(symmetryDarkInterval);
		
		/*
		 * RATIO
		 */
		RatioExtractor ratio_ext = new RatioExtractor("Sharpen / Original"); 
        ratio_ext.setColorMode(ImageHelper.LUMINANCE); 
        ratio_ext.setFilters1(new SharpenFilter(), new CannyEdgeFilter()); 
        ratio_ext.setFilters2(new CannyEdgeFilter()); 
        extractors.add(ratio_ext); 
		
		/*
		 * -------------------------------------------------------------------------------
		 */
		
		SetCreator sc = new SetCreator(database, percentage, imgPerClas);
		Set<FeatureVector> trainSet = sc.getFullTrainingSet(extractors);
		Set<FeatureVector> testSet = sc.getFullTestSet(extractors);
		
		klas = new Classification(classifier,extractors,sc.getClasses());
		klas.loadSets(trainSet, testSet);
		
		if(savePath != null)
			klas.saveToFile(savePath);
	}
	
	public static void FloatArrayPrinter(float[] fa, String message){
		System.out.print(message+" ");
		for(float f:fa)
			System.out.print(f+" ");
		System.out.println();
	}
	
	/**
	 * .JPG -> .jpg
	 * XXX(n).jpeg -> baci upozorenje
	 * @param path base directory
	 */
	public static void fixExtensions(String path){
		File root = new File( path );
        File[] list = root.listFiles();

        for ( File f : list ) {
            if ( f.isDirectory() ) {
                fixExtensions( f.getAbsolutePath() );
           }
            else {
    			String[] s = f.getAbsolutePath().split("\\.");
    			
    			if(s[1].compareToIgnoreCase("jpeg")==0)
    				System.out.println("----------->"+s[0]+"."+s[1].toLowerCase());    				
    			else
    				f.renameTo(new File(s[0]+"."+s[1].toLowerCase()));
    			
            }
        }
	}

}
